Class Goal : Replicate the chart below

The chart below uses a combination of selective highlighting of certain lines along with annotations to show the impact of genocides on life expectancy (since 1950). Our aim is to retrace the steps I took to create this chart and recreate it.

Get the data ready

Before we start, here is the list of packages we will be using

  1. tidyverse (ggplot + dplyr)
  2. gapminder
  3. hrbrthemes

You probable do not have hrbrthemes installed on your system. If you do not, then go ahead and install it.

Step 1: Load the three packages using library()

── Attaching packages ─────────────────────────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 3.1.1       ✔ purrr   0.3.2  
✔ tibble  2.1.1       ✔ dplyr   0.8.0.1
✔ tidyr   0.8.3       ✔ stringr 1.4.0  
✔ readr   1.3.1       ✔ forcats 0.4.0  
── Conflicts ────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()

Step 2: Identify the rate of change for life expectancy.

The chart identifies countries that experienced a drop in life expectancy that is greater than 15% at any point during the entire set of years for a particular country. This means that we have to calculate the rate of change for life expectancy. This can be calculated as the difference between the life expectancy in a current year from the previous observation in the data divided by the previous observation. In other words if the life expectancy in a country was 100 last observation and 95 this year. Then the rate of change would be (95 - 100)/100 = -5 % i.e. a drop of 5%.

We can identify the previous years life expectancy using lag(). I am going to illustrate this using data for the country of Afghanistan. I also keep only those columns that I am interested in for this analysis.

the order matters

Our next task is to calculate the rate of change in life expectancy using the formula we discussed earlier.

Now your task is to recreate this calculation for the entire gapminder dataset. Save your output in a variable called plot_data.

A few things to consider before you start. The code above is specific to a single country. How would you make sure the same calculation is replicated for each country in the data? Or rather think about how to group this data. Visually confirm that they lagged values are being calculated correctly.

Step 3: Identify the countries that experience drops in life expectancy that is greater than 15%.

The best way to calculate this is to first find the minimum rate of change for life expectancy for the entire set of years for a country and compare it with 15%. In the case of the Afghanistan data here is how this calculation looks. The important thing to note here is that if even a single value in the country’s panel of data is below the threshold then we want to make the entire country as “Sharp Decline”.

You can also use any() to do this h/t Zeenat.

Try and replicate this for plot_data you saved earlier. Before you start, consider how to group the data so that you can find the minimum rate of change in life expectancy for each country so that it can compared with -15. If there is a single value that is less than -15% for a country then the entire country should be marked as “Sharp Decline”.

Step 4: Confirm that you did this correctly.

Identify the distinct() or unique() countries that experienced “Sharp Declines” (drop of more than 15% in life expectancy). This should yield the following list of countries - Botswana, Cambodia, Lesotho, Rwands, Swaziland and Zimbabwe.

Make the plot

Now lets create the plot. Our first task is to create the base line plot which has one line for each country. Below is my first attempt.

This looks weird. Right now the line geom is drawing a line for each combination of year and lifeExp without grouping it by countries. Correct, the plot above by mapping the group aesthetic to the country variable. You will need to apply this on the data you created previously since you don’t have access to my data.

The next task is to assign the variable that marks wether there was a sharp decline in life expectancy as the color of each line.

Looking good….However the colors of the lines don’t match those in the chart that we are trying to copy. We can fix that by manually mapping the values to colors using scale_color_manual(). This function simply asks ggplot to ignore the default mapping of colors and instead use that specified within scale_color_manual().

This is looking better. However, the grey lines are too strong and hiding the red ones. Lets try to map the alpha aesthetic to the change_type variable as well to fix this.

Hmmm… that did not work well. This is because ggplot is automatically assigning alpha values (one for “Sharp Decline” and another for “Stable). Use the same pattern as above but use scale_alpha_manual() instead to set the alpha aesthetic to 1 if”Sharp Decline" and 0.3 if “Stable”.

Now the basic chart is ready. Lets now start working on making this look good. First I add the theme_ft_rc() from hrbrthemes. Like ggthemes that you have used before hrbrthemes is just another extension of ggplot that gives some additional themes and a few helper functions. Visit this github repo for more information on it. theme

Nice! Now lets use the theme function to do some more changes to this plot. First lets set the x axis title to blank.

Your turn… Remove the legend by setting legend.position = “none” within the theme() function.

This chart is now ready for some annotations.

Annotate the chart

While it is possible to annotate your charts programatically it is often difficult to exert fine control on placement of different elements just using code. So for this final stage I usually recommend manually specifying elements (rather than mapping them through data)

Next let’s add annotation to the plot indicating the first dip for Cambodia.

Now repeat this for Rwanda as well.

YOUR CODE HERE.

The next step is to add a point to indicate the lowest value. Lets first try it for Cambodia.

Now do the same for Rwanda.

YOUR CODE HERE.

Now the final stage is to add the annotation for the sub saharan countries that went through the AIDS epidemic.

Adjust the position and shape of the rectangle so that it looks similar to the final plot and add arrows and text labels to complete this plot!

YOUR CODE HERE

LS0tCnRpdGxlOiAiQ2xhc3MgMjQgLSBJbiBjbGFzcyBleGVyY2lzZXMiCmF1dGhvcjogSGFyaSBTdWJoYXNoCmRhdGU6ICJEYXRlIGNyZWF0ZWQ6IGByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGhpZ2hsaWdodDogaGFkZG9jawogICAgc21hcnQ6IHllcwogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBkZl9wcmludDogcGFnZWQKLS0tCgoqKkNsYXNzIEdvYWwqKiA6IFJlcGxpY2F0ZSB0aGUgY2hhcnQgYmVsb3cKClRoZSBjaGFydCBiZWxvdyB1c2VzIGEgY29tYmluYXRpb24gb2Ygc2VsZWN0aXZlIGhpZ2hsaWdodGluZyBvZiBjZXJ0YWluIGxpbmVzIGFsb25nIHdpdGggYW5ub3RhdGlvbnMgdG8gc2hvdyB0aGUgaW1wYWN0IG9mIGdlbm9jaWRlcyBvbiBsaWZlIGV4cGVjdGFuY3kgKHNpbmNlIDE5NTApLiBPdXIgYWltIGlzIHRvIHJldHJhY2UgdGhlIHN0ZXBzIEkgdG9vayB0byBjcmVhdGUgdGhpcyBjaGFydCBhbmQgcmVjcmVhdGUgaXQuCgpgYGB7ciwgZWNobz1GQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxpZmVfZXgucG5nIikKYGBgCgoKCiMjIEdldCB0aGUgZGF0YSByZWFkeQoKQmVmb3JlIHdlIHN0YXJ0LCBoZXJlIGlzIHRoZSBsaXN0IG9mIHBhY2thZ2VzIHdlIHdpbGwgYmUgdXNpbmcKCjEuIHRpZHl2ZXJzZSAoZ2dwbG90ICsgZHBseXIpCjIuIGdhcG1pbmRlcgozLiBocmJydGhlbWVzCgpZb3UgcHJvYmFibGUgZG8gbm90IGhhdmUgaHJicnRoZW1lcyBpbnN0YWxsZWQgb24geW91ciBzeXN0ZW0uIElmIHlvdSBkbyBub3QsIHRoZW4gZ28gYWhlYWQgYW5kIGluc3RhbGwgaXQuCgoqKlN0ZXAgMSoqOiBMb2FkIHRoZSB0aHJlZSBwYWNrYWdlcyB1c2luZyBgbGlicmFyeSgpYAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKTsgbGlicmFyeShnYXBtaW5kZXIpOyBsaWJyYXJ5KGhyYnJ0aGVtZXMpCmBgYAoKCioqU3RlcCAyKio6IElkZW50aWZ5IHRoZSByYXRlIG9mIGNoYW5nZSBmb3IgbGlmZSBleHBlY3RhbmN5LiAKClRoZSBjaGFydCBpZGVudGlmaWVzIGNvdW50cmllcyB0aGF0IGV4cGVyaWVuY2VkIGEgZHJvcCBpbiBsaWZlIGV4cGVjdGFuY3kgdGhhdCBpcyBncmVhdGVyIHRoYW4gMTUlIGF0IGFueSBwb2ludCBkdXJpbmcgdGhlIGVudGlyZSBzZXQgb2YgeWVhcnMgZm9yIGEgcGFydGljdWxhciBjb3VudHJ5LiBUaGlzIG1lYW5zIHRoYXQgd2UgaGF2ZSB0byBjYWxjdWxhdGUgdGhlIHJhdGUgb2YgY2hhbmdlIGZvciBsaWZlIGV4cGVjdGFuY3kuIFRoaXMgY2FuIGJlIGNhbGN1bGF0ZWQgYXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgbGlmZSBleHBlY3RhbmN5IGluIGEgY3VycmVudCB5ZWFyIGZyb20gdGhlIHByZXZpb3VzIG9ic2VydmF0aW9uIGluIHRoZSBkYXRhIGRpdmlkZWQgYnkgdGhlIHByZXZpb3VzIG9ic2VydmF0aW9uLiBJbiBvdGhlciB3b3JkcyBpZiB0aGUgbGlmZSBleHBlY3RhbmN5IGluIGEgY291bnRyeSB3YXMgMTAwIGxhc3Qgb2JzZXJ2YXRpb24gYW5kIDk1IHRoaXMgeWVhci4gVGhlbiB0aGUgcmF0ZSBvZiBjaGFuZ2Ugd291bGQgYmUgKDk1IC0gMTAwKS8xMDAgPSAtNSAlIGkuZS4gYSBkcm9wIG9mIDUlLgoKV2UgY2FuIGlkZW50aWZ5IHRoZSBwcmV2aW91cyB5ZWFycyBsaWZlIGV4cGVjdGFuY3kgdXNpbmcgYGxhZygpYC4gSSBhbSBnb2luZyB0byBpbGx1c3RyYXRlIHRoaXMgdXNpbmcgZGF0YSBmb3IgdGhlIGNvdW50cnkgb2YgQWZnaGFuaXN0YW4uIEkgYWxzbyBrZWVwIG9ubHkgdGhvc2UgY29sdW1ucyB0aGF0IEkgYW0gaW50ZXJlc3RlZCBpbiBmb3IgdGhpcyBhbmFseXNpcy4KYGBge3J9CiMjIHNob3cgdGhlIGxhZ2dlZCB2YWx1ZSBmb3IganVzdCBBZmdoYW5pc3RhbgpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb3VudHJ5ID09ICJBZmdoYW5pc3RhbiIpICU+JSAKICBzZWxlY3QoY291bnRyeSwgeWVhciwgbGlmZUV4cCkgJT4lIAogIG11dGF0ZShsYWdfbGlmZUV4cCA9IGxhZyhsaWZlRXhwKSkKCmBgYAoKdGhlIG9yZGVyIG1hdHRlcnMKYGBge3J9CmdhcG1pbmRlciAlPiUgCiAgZmlsdGVyKGNvdW50cnkgPT0gIkFmZ2hhbmlzdGFuIikgJT4lIAogIHNlbGVjdChjb3VudHJ5LCB5ZWFyLCBsaWZlRXhwKSAlPiUgCiAgYXJyYW5nZShkZXNjKHllYXIpKSAlPiUgCiAgbXV0YXRlKGxhZ19saWZlRXhwID0gbGFnKGxpZmVFeHApKQpgYGAKCk91ciBuZXh0IHRhc2sgaXMgdG8gY2FsY3VsYXRlIHRoZSByYXRlIG9mIGNoYW5nZSBpbiBsaWZlIGV4cGVjdGFuY3kgdXNpbmcgdGhlIGZvcm11bGEgd2UgZGlzY3Vzc2VkIGVhcmxpZXIuCmBgYHtyfQojIyBjYWxjdWxhdGUgdGhlIHJhdGUgb2YgY2hhbmdlCmdhcG1pbmRlciAlPiUgCiAgZmlsdGVyKGNvdW50cnkgPT0gIkFmZ2hhbmlzdGFuIikgJT4lIAogIHNlbGVjdChjb3VudHJ5LCB5ZWFyLCBsaWZlRXhwKSAlPiUgCiAgbXV0YXRlKGxhZ19saWZlRXhwID0gbGFnKGxpZmVFeHApLAogICAgICAgICBjaGFuZ2VfbGlmZUV4cCA9IChsaWZlRXhwIC0gbGFnX2xpZmVFeHApIC8gbGFnX2xpZmVFeHAgKiAxMDApCmBgYAoKTm93IHlvdXIgdGFzayBpcyB0byByZWNyZWF0ZSB0aGlzIGNhbGN1bGF0aW9uIGZvciB0aGUgKmVudGlyZSogZ2FwbWluZGVyIGRhdGFzZXQuIFNhdmUgeW91ciBvdXRwdXQgaW4gYSB2YXJpYWJsZSBjYWxsZWQgYHBsb3RfZGF0YWAuIAoKQSBmZXcgdGhpbmdzIHRvIGNvbnNpZGVyIGJlZm9yZSB5b3Ugc3RhcnQuIFRoZSBjb2RlIGFib3ZlIGlzIHNwZWNpZmljIHRvIGEgc2luZ2xlIGNvdW50cnkuIEhvdyB3b3VsZCB5b3UgbWFrZSBzdXJlIHRoZSBzYW1lIGNhbGN1bGF0aW9uIGlzIHJlcGxpY2F0ZWQgZm9yIGVhY2ggY291bnRyeSBpbiB0aGUgZGF0YT8gT3IgcmF0aGVyIHRoaW5rIGFib3V0IGhvdyB0byBncm91cCB0aGlzIGRhdGEuIFZpc3VhbGx5IGNvbmZpcm0gdGhhdCB0aGV5IGxhZ2dlZCB2YWx1ZXMgYXJlIGJlaW5nIGNhbGN1bGF0ZWQgY29ycmVjdGx5LgoKCmBgYHtyfQpwbG90X2RhdGEgPC0gZ2FwbWluZGVyICU+JSAKICBzZWxlY3QoY291bnRyeSwgeWVhciwgbGlmZUV4cCkgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBtdXRhdGUoY2hhbmdlX2xpZmVFeHAgPSAobGlmZUV4cCAtIGxhZyhsaWZlRXhwKSkgLyBsYWcobGlmZUV4cCkgKiAxMDApCgpwbG90X2RhdGEKYGBgCgoKKipTdGVwIDMqKjogSWRlbnRpZnkgdGhlIGNvdW50cmllcyB0aGF0IGV4cGVyaWVuY2UgZHJvcHMgaW4gbGlmZSBleHBlY3RhbmN5IHRoYXQgaXMgZ3JlYXRlciB0aGFuIDE1JS4KClRoZSBiZXN0IHdheSB0byBjYWxjdWxhdGUgdGhpcyBpcyB0byBmaXJzdCBmaW5kIHRoZSBtaW5pbXVtIHJhdGUgb2YgY2hhbmdlIGZvciBsaWZlIGV4cGVjdGFuY3kgZm9yIHRoZSBlbnRpcmUgc2V0IG9mIHllYXJzIGZvciBhIGNvdW50cnkgYW5kIGNvbXBhcmUgaXQgd2l0aCAxNSUuIEluIHRoZSBjYXNlIG9mIHRoZSBBZmdoYW5pc3RhbiBkYXRhIGhlcmUgaXMgaG93IHRoaXMgY2FsY3VsYXRpb24gbG9va3MuIFRoZSBpbXBvcnRhbnQgdGhpbmcgdG8gbm90ZSBoZXJlIGlzIHRoYXQgaWYgZXZlbiBhIHNpbmdsZSB2YWx1ZSBpbiB0aGUgY291bnRyeSdzIHBhbmVsIG9mIGRhdGEgaXMgYmVsb3cgdGhlIHRocmVzaG9sZCB0aGVuIHdlIHdhbnQgdG8gbWFrZSB0aGUgKmVudGlyZSogY291bnRyeSBhcyAiU2hhcnAgRGVjbGluZSIuCgpgYGB7cn0KIyMgc2hvdyB0aGlzIGNhbGN1bGF0aW9uIGZvciBBZmdoYW5pc3RhbgpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb3VudHJ5ID09ICJBZmdoYW5pc3RhbiIpICU+JSAKICBzZWxlY3QoY291bnRyeSwgeWVhciwgbGlmZUV4cCkgJT4lIAogIG11dGF0ZShsYWdfbGlmZUV4cCA9IGxhZyhsaWZlRXhwKSwKICAgICAgICAgY2hhbmdlX2xpZmVFeHAgPSAobGlmZUV4cCAtIGxhZ19saWZlRXhwKSAvIGxhZ19saWZlRXhwICogMTAwLAogICAgICAgICBjaGFuZ2VfdHlwZSA9IGlmX2Vsc2UobWluKGNoYW5nZV9saWZlRXhwLCBuYS5ybSA9IFQpIDwgLTE1LCAiU2hhcnAgRGVjbGluZSIsICJTdGFibGUiKSkKYGBgCgpZb3UgY2FuIGFsc28gdXNlIGBhbnkoKWAgdG8gZG8gdGhpcyBoL3QgWmVlbmF0LgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBmaWx0ZXIoY291bnRyeSA9PSAiQWZnaGFuaXN0YW4iKSAlPiUgCiAgc2VsZWN0KGNvdW50cnksIHllYXIsIGxpZmVFeHApICU+JSAKICBtdXRhdGUobGFnX2xpZmVFeHAgPSBsYWcobGlmZUV4cCksCiAgICAgICAgIGNoYW5nZV9saWZlRXhwID0gKGxpZmVFeHAgLSBsYWdfbGlmZUV4cCkgLyBsYWdfbGlmZUV4cCAqIDEwMCwKICAgICAgICAgY2hhbmdlX3R5cGUgPSBpZl9lbHNlKGFueShjaGFuZ2VfbGlmZUV4cCA8IDEsIG5hLnJtID0gVCksICJTaGFycCBEZWNsaW5lIiwgIlN0YWJsZSIpKQpgYGAKClRyeSBhbmQgcmVwbGljYXRlIHRoaXMgZm9yIGBwbG90X2RhdGFgIHlvdSBzYXZlZCBlYXJsaWVyLiBCZWZvcmUgeW91IHN0YXJ0LCBjb25zaWRlciBob3cgdG8gZ3JvdXAgdGhlIGRhdGEgc28gdGhhdCB5b3UgY2FuIGZpbmQgdGhlIG1pbmltdW0gcmF0ZSBvZiBjaGFuZ2UgaW4gbGlmZSBleHBlY3RhbmN5IGZvciBlYWNoIGNvdW50cnkgc28gdGhhdCBpdCBjYW4gY29tcGFyZWQgd2l0aCAtMTUuIElmIHRoZXJlIGlzIGEgc2luZ2xlIHZhbHVlIHRoYXQgaXMgbGVzcyB0aGFuIC0xNSUgZm9yIGEgY291bnRyeSB0aGVuIHRoZSBlbnRpcmUgY291bnRyeSBzaG91bGQgYmUgbWFya2VkIGFzICJTaGFycCBEZWNsaW5lIi4KCmBgYHtyfQpwbG90X2RhdGEgPC0gZ2FwbWluZGVyICU+JSAKICBzZWxlY3QoY291bnRyeSwgeWVhciwgbGlmZUV4cCkgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBtdXRhdGUoY2hhbmdlX2xpZmVFeHAgPSAobGlmZUV4cCAtIGxhZyhsaWZlRXhwKSkgLyBsYWcobGlmZUV4cCkgKiAxMDAsCiAgICAgICAgIGNoYW5nZV90eXBlID0gaWZfZWxzZShhbnkoY2hhbmdlX2xpZmVFeHAgPCAtMTUsIG5hLnJtID0gVCksICJTaGFycCBEZWNsaW5lIiwgIlN0YWJsZSIpKQoKcGxvdF9kYXRhICU+JSAKICBmaWx0ZXIoY2hhbmdlX3R5cGUgPT0gIlNoYXJwIERlY2xpbmUiKSAlPiUgCiAgZGlzdGluY3QoY291bnRyeSkKYGBgCgoKCioqU3RlcCA0Kio6IENvbmZpcm0gdGhhdCB5b3UgZGlkIHRoaXMgY29ycmVjdGx5LgoKSWRlbnRpZnkgdGhlIGBkaXN0aW5jdCgpYCBvciBgdW5pcXVlKClgIGNvdW50cmllcyB0aGF0IGV4cGVyaWVuY2VkICJTaGFycCBEZWNsaW5lcyIgKGRyb3Agb2YgbW9yZSB0aGFuIDE1JSBpbiBsaWZlIGV4cGVjdGFuY3kpLiBUaGlzIHNob3VsZCB5aWVsZCB0aGUgZm9sbG93aW5nIGxpc3Qgb2YgY291bnRyaWVzIC0gQm90c3dhbmEsIENhbWJvZGlhLCBMZXNvdGhvLCBSd2FuZHMsIFN3YXppbGFuZCBhbmQgWmltYmFid2UuCgpgYGB7cn0KcGxvdF9kYXRhCmBgYAoKCgojIyBNYWtlIHRoZSBwbG90Ck5vdyBsZXRzIGNyZWF0ZSB0aGUgcGxvdC4gT3VyIGZpcnN0IHRhc2sgaXMgdG8gY3JlYXRlIHRoZSBiYXNlIGxpbmUgcGxvdCB3aGljaCBoYXMgb25lIGxpbmUgZm9yIGVhY2ggY291bnRyeS4gQmVsb3cgaXMgbXkgZmlyc3QgYXR0ZW1wdC4KYGBge3Igd2l0aG91dCBncm91cGluZ30KIyMgYmFzaWMgY2hhcnQgd2l0aG91dCBncm91cGluZwpnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YSwgbWFwcGluZyA9IGFlcyh4ID0geWVhciwgeSA9IGxpZmVFeHApKSArCiAgZ2VvbV9saW5lKCkKYGBgCgpUaGlzIGxvb2tzIHdlaXJkLiBSaWdodCBub3cgdGhlIGxpbmUgZ2VvbSBpcyBkcmF3aW5nIGEgbGluZSBmb3IgZWFjaCBjb21iaW5hdGlvbiBvZiB5ZWFyIGFuZCBsaWZlRXhwIHdpdGhvdXQgZ3JvdXBpbmcgaXQgYnkgY291bnRyaWVzLiBDb3JyZWN0LCB0aGUgcGxvdCBhYm92ZSBieSBtYXBwaW5nIHRoZSBgZ3JvdXBgIGFlc3RoZXRpYyB0byB0aGUgY291bnRyeSB2YXJpYWJsZS4gWW91IHdpbGwgbmVlZCB0byBhcHBseSB0aGlzIG9uIHRoZSBkYXRhIHlvdSBjcmVhdGVkIHByZXZpb3VzbHkgc2luY2UgeW91IGRvbid0IGhhdmUgYWNjZXNzIHRvIG15IGRhdGEuCmBgYHtyfQpwbG90X2RhdGEgJT4lIAogIGZpbHRlcihjb3VudHJ5ICVpbiUgYygnQWZnaGFuaXN0YW4nLCAiQWxiYW5pYSIsICJDYW5hZGEiKSkKYGBgCgpgYGB7cn0KcGxvdF9kYXRhICU+JSAKICBmaWx0ZXIoY291bnRyeSAlaW4lIGMoJ0FmZ2hhbmlzdGFuJywgIkFsYmFuaWEiLCAiQ2FuYWRhIikpICU+JSAKICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0geWVhciwgeSA9IGxpZmVFeHApKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyhjb2xvdXIgPSBjb3VudHJ5KSkKYGBgCgoKYGBge3J9CmdncGxvdChkYXRhID0gcGxvdF9kYXRhLCBtYXBwaW5nID0gYWVzKHggPSB5ZWFyLCB5ID0gbGlmZUV4cCwgZ3JvdXAgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpCmBgYAoKClRoZSBuZXh0IHRhc2sgaXMgdG8gYXNzaWduIHRoZSB2YXJpYWJsZSB0aGF0IG1hcmtzIHdldGhlciB0aGVyZSB3YXMgYSBzaGFycCBkZWNsaW5lIGluIGxpZmUgZXhwZWN0YW5jeSBhcyB0aGUgY29sb3Igb2YgZWFjaCBsaW5lLgoKYGBge3J9CmdncGxvdChkYXRhID0gcGxvdF9kYXRhLCBtYXBwaW5nID0gYWVzKHggPSB5ZWFyLCB5ID0gbGlmZUV4cCwgZ3JvdXAgPSBjb3VudHJ5LCBjb2xvdXIgPSBjaGFuZ2VfdHlwZSkpICsKICBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YSwgbWFwcGluZyA9IGFlcyh4ID0geWVhciwgeSA9IGxpZmVFeHAsIGdyb3VwID0gY291bnRyeSwgY29sb3VyID0gY2hhbmdlX3R5cGUpKSArCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJTaGFycCBEZWNsaW5lIiA9ICJyZWQiLCAiU3RhYmxlIiA9ICJncmV5IikpCmBgYAoKCgpMb29raW5nIGdvb2QuLi4uSG93ZXZlciB0aGUgY29sb3JzIG9mIHRoZSBsaW5lcyBkb24ndCBtYXRjaCB0aG9zZSBpbiB0aGUgY2hhcnQgdGhhdCB3ZSBhcmUgdHJ5aW5nIHRvIGNvcHkuIFdlIGNhbiBmaXggdGhhdCBieSBtYW51YWxseSBtYXBwaW5nIHRoZSB2YWx1ZXMgdG8gY29sb3JzIHVzaW5nIGBzY2FsZV9jb2xvcl9tYW51YWwoKWAuIFRoaXMgZnVuY3Rpb24gc2ltcGx5IGFza3MgZ2dwbG90IHRvIGlnbm9yZSB0aGUgZGVmYXVsdCBtYXBwaW5nIG9mIGNvbG9ycyBhbmQgaW5zdGVhZCB1c2UgdGhhdCBzcGVjaWZpZWQgd2l0aGluIGBzY2FsZV9jb2xvcl9tYW51YWwoKWAuCgpgYGB7cn0KIyMgdXNlIHRoZSBzY2FsZV9jb2xvcl9tYW51YWwgdG8gbWFudWFsbHkgbWFwIGNvbG9ycyB0byB2YWx1ZXMKCmBgYAoKVGhpcyBpcyBsb29raW5nIGJldHRlci4gSG93ZXZlciwgdGhlIGdyZXkgbGluZXMgYXJlIHRvbyBzdHJvbmcgYW5kIGhpZGluZyB0aGUgcmVkIG9uZXMuIExldHMgdHJ5IHRvIG1hcCB0aGUgYWxwaGEgYWVzdGhldGljIHRvIHRoZSBjaGFuZ2VfdHlwZSB2YXJpYWJsZSBhcyB3ZWxsIHRvIGZpeCB0aGlzLgoKYGBge3J9CiMjIG1hcCB0aGUgY2hhbmdlX3R5cGUgdG8gYWxwaGEgYWVzdGhldGljCmdncGxvdChkYXRhID0gcGxvdF9kYXRhLCBtYXBwaW5nID0gYWVzKHggPSB5ZWFyLCB5ID0gbGlmZUV4cCwgZ3JvdXAgPSBjb3VudHJ5LCBjb2xvdXIgPSBjaGFuZ2VfdHlwZSwgYWxwaGEgPSBjaGFuZ2VfdHlwZSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gInJlZCIsICJTdGFibGUiID0gImdyZXkiKSkKYGBgCgpIbW1tLi4uIHRoYXQgZGlkIG5vdCB3b3JrIHdlbGwuIFRoaXMgaXMgYmVjYXVzZSBnZ3Bsb3QgaXMgYXV0b21hdGljYWxseSBhc3NpZ25pbmcgYWxwaGEgdmFsdWVzIChvbmUgZm9yICJTaGFycCBEZWNsaW5lIiBhbmQgYW5vdGhlciBmb3IgIlN0YWJsZSkuIFVzZSB0aGUgc2FtZSBwYXR0ZXJuIGFzIGFib3ZlIGJ1dCB1c2UgYHNjYWxlX2FscGhhX21hbnVhbCgpYCBpbnN0ZWFkIHRvIHNldCB0aGUgYWxwaGEgYWVzdGhldGljIHRvIDEgaWYgIlNoYXJwIERlY2xpbmUiIGFuZCAwLjMgaWYgIlN0YWJsZSIuCgoKYGBge3J9CmdncGxvdChkYXRhID0gcGxvdF9kYXRhLCBtYXBwaW5nID0gYWVzKHggPSB5ZWFyLCB5ID0gbGlmZUV4cCwgZ3JvdXAgPSBjb3VudHJ5LCBjb2xvdXIgPSBjaGFuZ2VfdHlwZSwgYWxwaGEgPSBjaGFuZ2VfdHlwZSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gInJlZCIsICJTdGFibGUiID0gImdyZXkiKSkgKwogIHNjYWxlX2FscGhhX21hbnVhbCh2YWx1ZXMgPSBjKCJTaGFycCBEZWNsaW5lIiA9IDEsICJTdGFibGUiID0gMC4zKSkKYGBgCgoKTm93IHRoZSBiYXNpYyBjaGFydCBpcyByZWFkeS4gTGV0cyBub3cgc3RhcnQgd29ya2luZyBvbiBtYWtpbmcgdGhpcyBsb29rIGdvb2QuIEZpcnN0IEkgYWRkIHRoZSBgdGhlbWVfZnRfcmMoKWAgZnJvbSBocmJydGhlbWVzLiBMaWtlIGdndGhlbWVzIHRoYXQgeW91IGhhdmUgdXNlZCBiZWZvcmUgaHJicnRoZW1lcyBpcyBqdXN0IGFub3RoZXIgZXh0ZW5zaW9uIG9mIGdncGxvdCB0aGF0IGdpdmVzIHNvbWUgYWRkaXRpb25hbCB0aGVtZXMgYW5kIGEgZmV3IGhlbHBlciBmdW5jdGlvbnMuIFZpc2l0IHRoaXMgW2dpdGh1YiByZXBvXShodHRwczovL2dpdGh1Yi5jb20vaHJicm1zdHIvaHJicnRoZW1lcykgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gaXQuIHRoZW1lCgpgYGB7cn0KIyMgYXBwbHkgdGhlbWVfZnRfcmMoKQoKZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG91ciA9IGNoYW5nZV90eXBlLCBhbHBoYSA9IGNoYW5nZV90eXBlKSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiU2hhcnAgRGVjbGluZSIgPSAicmVkIiwgIlN0YWJsZSIgPSAiZ3JleSIpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gMSwgIlN0YWJsZSIgPSAwLjMpKSArCiAgdGhlbWVfZnRfcmMoKQoKYGBgCgpOaWNlISBOb3cgbGV0cyB1c2UgdGhlIHRoZW1lIGZ1bmN0aW9uIHRvIGRvIHNvbWUgbW9yZSBjaGFuZ2VzIHRvIHRoaXMgcGxvdC4gRmlyc3QgbGV0cyBzZXQgdGhlIHggYXhpcyB0aXRsZSB0byBibGFuay4KCmBgYHtyfQojIyBzZXQgdGhlIGF4aXMgdGl0bGUgdG8gYmxhbmsKZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG91ciA9IGNoYW5nZV90eXBlLCBhbHBoYSA9IGNoYW5nZV90eXBlKSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiU2hhcnAgRGVjbGluZSIgPSAicmVkIiwgIlN0YWJsZSIgPSAiZ3JleSIpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gMSwgIlN0YWJsZSIgPSAwLjMpKSArCiAgdGhlbWVfZnRfcmMoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkKICApCmBgYAoKWW91ciB0dXJuLi4uIFJlbW92ZSB0aGUgbGVnZW5kIGJ5IHNldHRpbmcgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiIHdpdGhpbiB0aGUgYHRoZW1lKClgIGZ1bmN0aW9uLgoKCmBgYHtyfQojIyBzZXQgdGhlIGF4aXMgdGl0bGUgdG8gYmxhbmsKZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG91ciA9IGNoYW5nZV90eXBlLCBhbHBoYSA9IGNoYW5nZV90eXBlKSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiU2hhcnAgRGVjbGluZSIgPSAicmVkIiwgIlN0YWJsZSIgPSAiZ3JleSIpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gMSwgIlN0YWJsZSIgPSAwLjMpKSArCiAgdGhlbWVfZnRfcmMoKSArCiAgbGFicyh5ID0gIkxpZmUgRXhwZWN0YW5jeSIsCiAgICAgICB0aXRsZSA9ICJUaGUgaW1wYWN0IG9mIGdlbm9jaWRlcyBhbmQgdGhlIEFJRFMgZXBpZGVtaWMiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IGdhcG1pbmRlciIpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICkKYGBgCgoKCgoKVGhpcyBjaGFydCBpcyBub3cgcmVhZHkgZm9yIHNvbWUgYW5ub3RhdGlvbnMuCgoKCgojIyBBbm5vdGF0ZSB0aGUgY2hhcnQKV2hpbGUgaXQgaXMgcG9zc2libGUgdG8gYW5ub3RhdGUgeW91ciBjaGFydHMgcHJvZ3JhbWF0aWNhbGx5IGl0IGlzIG9mdGVuIGRpZmZpY3VsdCB0byBleGVydCBmaW5lIGNvbnRyb2wgb24gcGxhY2VtZW50IG9mIGRpZmZlcmVudCBlbGVtZW50cyBqdXN0IHVzaW5nIGNvZGUuIFNvIGZvciB0aGlzIGZpbmFsIHN0YWdlIEkgdXN1YWxseSByZWNvbW1lbmQgbWFudWFsbHkgc3BlY2lmeWluZyBlbGVtZW50cyAocmF0aGVyIHRoYW4gbWFwcGluZyB0aGVtIHRocm91Z2ggZGF0YSkKYGBge3J9CiMjIGFkZCB0aGUgdGl0bGUsIHN1YnRpdGxlLCB5LWF4aXMgbGFiZWxzIGFuZCBjYXB0aW9uCgpgYGAKCgpOZXh0IGxldCdzIGFkZCBhbm5vdGF0aW9uIHRvIHRoZSBwbG90IGluZGljYXRpbmcgdGhlIGZpcnN0IGRpcCBmb3IgQ2FtYm9kaWEuCgpgYGB7cn0KIyMgYWRkIGEgbGluZSBzZWdtZW50IHdpdGggYW4gYXJyb3cgYW5kIHRleHQgaW5kaWNhdGluZyB0aGUgZ2Vub2NpZGUgaW4gQ2FtYm9kaWEKZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG91ciA9IGNoYW5nZV90eXBlLCBhbHBoYSA9IGNoYW5nZV90eXBlKSkgKwogIGdlb21fbGluZSgpICsKICBhbm5vdGF0ZShnZW9tID0gInBvaW50IiwgeCA9IDE5NzcsIHkgPSAzMSwgc2hhcGUgPSAyMSwgY29sb3VyID0gInJlZCIsIGZpbGwgPSAiZmlyZWJyaWNrIikgKwogIGFubm90YXRlKGdlb20gPSAiY3VydmUiLCB4ID0gMTk3MiwgeGVuZCA9IDE5NzYuNSwgeSA9IDI4LCB5ZW5kID0gMzAsIGNvbG91ciA9ICJncmV5OTAiLCBjdXJ2YXR1cmUgPSAwLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjIwLCJjbSIpKSwgc2l6ZSA9IDAuNCkgKwogIGFubm90YXRlKGdlb20gPSAidGV4dCIsIHggPSAxOTY3LCAgeSA9IDI4LCBjb2xvdXIgPSAiZ3JleTkwIiwgbGFiZWwgPSBzdHJfd3JhcCgiQ2FtYm9kaWFuIGdlbm9jaWRlIHVuZGVyIEtobWVyIFJvdWdlIiwgd2lkdGggPSAxOCksIHNpemUgPSAyLjUpICsKICBhbm5vdGF0ZShnZW9tID0gInBvaW50IiwgeCA9IDE5OTIsIHkgPSAyMy41LCBzaGFwZSA9IDIxLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9ICJmaXJlYnJpY2siKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSAxOTg4LCB4ZW5kID0gMTk5MS41LCB5ID0gMjAsIHllbmQgPSAyMywgY29sb3VyID0gImdyZXk5MCIsIGN1cnZhdHVyZSA9IDAuMywgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMjAsImNtIikpLCBzaXplID0gMC40KSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IDE5ODQsICB5ID0gMjIsIGNvbG91ciA9ICJncmV5OTAiLCBsYWJlbCA9IHN0cl93cmFwKCJHZW5vY2lkZSBhZ2FpbnN0IHRoZSBUdXRzaSBpbiBSd2FuZGEiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDIuNSkgKwogIGFubm90YXRlKGdlb20gPSAicmVjdCIsIHhtaW4gPSAxOTkwLCB4bWF4ID0gMjAwNSwgeW1pbiA9IDQwLCB5bWF4ID0gNjIsIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gInJlZCIsIGFscGhhID0gMC4zKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IDIwMDIsICB5ID0gMzAsIGNvbG91ciA9ICJncmV5OTAiLCBsYWJlbCA9IHN0cl93cmFwKCJUaGUgQUlEUyBlcGlkZW1pYyBpbiBzdWItc2FoYXJhbiBBZnJpY2EiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDIuNSkgKwogIGFubm90YXRlKGdlb20gPSAiY3VydmUiLCB4ID0gMjAwNywgeGVuZCA9IDIwMDUsIHkgPSAzMCwgeWVuZCA9IDQwLCBjb2xvdXIgPSAiZ3JleTkwIiwgY3VydmF0dXJlID0gMC44LCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC4yMCwiY20iKSksIHNpemUgPSAwLjQpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiU2hhcnAgRGVjbGluZSIgPSAicmVkIiwgIlN0YWJsZSIgPSAiZ3JleSIpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gMSwgIlN0YWJsZSIgPSAwLjMpKSArCiAgdGhlbWVfZnRfcmMoKSArCiAgbGFicyh5ID0gIkxpZmUgRXhwZWN0YW5jeSIsCiAgICAgICB0aXRsZSA9ICJUaGUgaW1wYWN0IG9mIGdlbm9jaWRlcyBhbmQgdGhlIEFJRFMgZXBpZGVtaWMiLAogICAgICAgc3VidGl0bGUgPSAiQ291bnRyaWVzIHRoYXQgZXhwZXJpZW5jZWQgYSBkcm9wIG9mIG1vcmUgdGhhbiAxNSUgaW4gbGlmZSBleHBlY3RhbmN5IGFyZSBoaWdobGlnaHRlZCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogZ2FwbWluZGVyIikgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiCiAgKQoKCmBgYAoKCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG91ciA9IGNoYW5nZV90eXBlLCBhbHBoYSA9IGNoYW5nZV90eXBlKSkgKwogIGdlb21fbGluZSgpICsKICBhbm5vdGF0ZShnZW9tID0gImN1cnZlIiwgeCA9IDE5NzAsIHhlbmQgPSAxOTc3LCB5ID0gMjgsIHllbmQgPSAzMCwgY29sb3VyID0gImdyZXk3MCIsIGN1cnZhdHVyZSA9IDAuMywgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMjAsImNtIikpKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IDE5NzAsICB5ID0gMjgsIGNvbG91ciA9ICJncmV5NzAiLCBsYWJlbCA9ICJDYW1ib2RpYSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiU2hhcnAgRGVjbGluZSIgPSAicmVkIiwgIlN0YWJsZSIgPSAiZ3JleSIpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoIlNoYXJwIERlY2xpbmUiID0gMSwgIlN0YWJsZSIgPSAwLjMpKSArCiAgdGhlbWVfZnRfcmMoKSArCiAgbGFicyh5ID0gIkxpZmUgRXhwZWN0YW5jeSIsCiAgICAgICB0aXRsZSA9ICJUaGUgaW1wYWN0IG9mIGdlbm9jaWRlcyBhbmQgdGhlIEFJRFMgZXBpZGVtaWMiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IGdhcG1pbmRlciIpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICkKYGBgCgoKCgoKCgoKTm93IHJlcGVhdCB0aGlzIGZvciBSd2FuZGEgYXMgd2VsbC4KCgpZT1VSIENPREUgSEVSRS4KCgoKCgoKVGhlIG5leHQgc3RlcCBpcyB0byBhZGQgYSBwb2ludCB0byBpbmRpY2F0ZSB0aGUgbG93ZXN0IHZhbHVlLiBMZXRzIGZpcnN0IHRyeSBpdCBmb3IgQ2FtYm9kaWEuCgpgYGB7cn0KCiMjIGFkZCBhIHBvaW50IGluZGljYXRpbmcgdGhlIHBvc2l0aW9uIG9mIHRoZSBtaW4gdmFsdWUgZm9yIENhbWJvZGlhCgpgYGAKCgoKTm93IGRvIHRoZSBzYW1lIGZvciBSd2FuZGEuCgpZT1VSIENPREUgSEVSRS4KCgoKCk5vdyB0aGUgZmluYWwgc3RhZ2UgaXMgdG8gYWRkIHRoZSBhbm5vdGF0aW9uIGZvciB0aGUgc3ViIHNhaGFyYW4gY291bnRyaWVzIHRoYXQgd2VudCB0aHJvdWdoIHRoZSBBSURTIGVwaWRlbWljLgoKYGBge3J9CgpgYGAKCkFkanVzdCB0aGUgcG9zaXRpb24gYW5kIHNoYXBlIG9mIHRoZSByZWN0YW5nbGUgc28gdGhhdCBpdCBsb29rcyBzaW1pbGFyIHRvIHRoZSBmaW5hbCBwbG90IGFuZCBhZGQgYXJyb3dzIGFuZCB0ZXh0IGxhYmVscyB0byBjb21wbGV0ZSB0aGlzIHBsb3QhCgpZT1VSIENPREUgSEVSRQoKCg==